print('#############实现一个可变参数的求和，不需要立刻求和，而是在后面的代码中，根据需要再计算#############')


def lazy_sum(*args):
    """
    懒求和
    :param args: 可变参数
    :return:
    """
    def sum_num():
        ax = 0
        for n in args:
            ax = ax + n
        return ax

    return sum_num


f = lazy_sum(2, 3, 4, 5, 6)
print(f)
print(f())
print('#############调用lazy_sum()时，每次调用都会返回一个新的函数#############')
f2 = lazy_sum(2, 3, 4, 5, 6)
print('f:', f)
print('f2:', f2)
print('f==f2:', f == f2)
print('f()==f2():', f() == f2())
print('#############返回闭包时牢记一点：返回函数不要引用任何循环变量，或者后续会发生变化的变量。 #############')


def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i * i

        fs.append(f)
    return fs


f1, f2, f3 = count()
print(count())
print(f1())
print(f2())
print(f3())
print('#############返回闭包时牢记一点：返回函数不要引用任何循环变量，或者后续会发生变化的变量。（一定要引用）#############')


def count():
    def f(j):
        def g():
            return j * j

        return g

    fs = []
    for i in range(1, 4):
        fs.append(f(i))  # f(i)立刻被执行，因此i的当前值被传入f()
    return fs


print(count())
f1, f2, f3 = count()
print(f1)
print(f2)
print(f3)
print('#############利用闭包返回一个计数器函数，每次调用它返回递增整数#############')


def create_counter():
    a = [0]

    def counter():
        a[0] += 1
        return a[0]

    return counter


fun = create_counter()
print(fun())
print(fun())
print(fun())
print(fun())
print('#############利用闭包返回一个计数器函数，每次调用它返回递增整数，第二种方式#############')


def create_counter_2():
    i = 0

    def counter():
        nonlocal i
        i += 1
        return i

    return counter


fun_2 = create_counter_2()
print(fun_2())
print(fun_2())
print(fun_2())
print(fun_2())